package main;

public class FloatArrayGrid extends TwoDGrid {
	
	/**
	 * Constructor. Takes the grid size as argument. This grid size should NOT
	 * include the borders.
	 * @param sizeX
	 * @param sizeY
	 * @throws InvalidArgumentException if sizeX or sizeY is <= 0
	 */
	public FloatArrayGrid(int sizeX, int sizeY) {
		if(sizeX > 0 && sizeY > 0) {
			grid = new float[sizeX+2][sizeY+2]; // Java guarrantees 0 init for all cells
			gridSizeX = sizeX;
			gridSizeY = sizeY;
			myAlgorithm = new FiniteDiffAlgorithmFloat(this);
		} else
			throw new java.lang.IllegalArgumentException("Grid sizes must be positive");
	}
	
	/**
	 * Convenience method to set all values on the border
	 * Equivalent to calling setValueAt over the borders
	 * @param which
	 * @param value
	 * @throws IllegalArgumentException if which is not SIDE_TOP, SIDE_LEFT
	 * SIDE_BOTTOM or SIDE_RIGHT
	 */
	public void initSideValue(int which, float value) {
		switch(which) {
		case SIDE_LEFT:
			for(int i=1; i < gridSizeY + 1; i++) {
				grid[0][i] = value;
			}
			break;
		case SIDE_TOP:
			for(int i=1; i < gridSizeX + 1; i++) {
				grid[i][0] = value;
			}
			break;		
		case SIDE_RIGHT:
			for(int i=1; i < gridSizeY + 1; i++) {
				grid[gridSizeX+1][i] = value;
			}
			break;
		case SIDE_BOTTOM:
			for(int i=1; i < gridSizeX + 1; i++) {
				grid[i][gridSizeY+1] = value;
			}
			break;	
		default:
			throw new java.lang.IllegalArgumentException("Invalid side");
		}
	}


	/* Inherited methods */
	public ICoordinate getNeighbor(ICoordinate coord, int direction) {
		if(coord instanceof XYCoordinate) 
			return coord.getNeighbor(direction);
		throw new java.lang.IllegalArgumentException("FloatArrayGrid expects XYCoordinates");
	}

	public boolean isDone() {
		if(myAlgorithm.getRelativeError() < 0.00001)
			return true;
		return false;
	}

	public String printCell(ICoordinate coord) {
		if(coord instanceof XYCoordinate) {
			XYCoordinate t = (XYCoordinate)coord;
			int x = t.getPositionX(), y = t.getPositionY();
      return decimalText.format(grid[x][y]);
		}
		
		throw new java.lang.IllegalArgumentException("FloatArrayGrid expects XYCoordinates");
	}

	public void stepGrid() {
		myAlgorithm.updateGrid( 
				new XYCoordinate[] {new XYCoordinate(1, 1), new XYCoordinate(gridSizeX, gridSizeY)});

	}

	
	public double getDoubleValue(ICoordinate coord) {
		throw new java.lang.UnsupportedOperationException("Float array does not support doubles");
	}

	
	public float getFloatValue(ICoordinate coord) {
		XYCoordinate xy = (XYCoordinate)coord;
		return grid[xy.getPositionX()][xy.getPositionY()];
	}


	public void setDoubleValue(ICoordinate coord, double value) {
		throw new java.lang.UnsupportedOperationException("Float array does not support doubles");
		
	}


	public void setFloatValue(ICoordinate coord, float value) {
		XYCoordinate xy = (XYCoordinate)coord;
		grid[xy.getPositionX()][xy.getPositionY()] = value;
		
	}

	public Double getDoubleObjValue(ICoordinate coord) {
		throw new java.lang.UnsupportedOperationException("Float array does not support double objects");
	}

	public Float getFloatObjValue(ICoordinate coord) {
		throw new java.lang.UnsupportedOperationException("Float array does not support float objects");
	}

	public void setDoubleObjValue(ICoordinate coord, Double value) {
		throw new java.lang.UnsupportedOperationException("Float array does not support double objects");
		
	}

	public void setFloatObjValue(ICoordinate coord, Float value) {
		throw new java.lang.UnsupportedOperationException("Float array does not support float objects");
		
	}
	
	/* Private variables */
	protected float[][] grid;
	protected FiniteDiffAlgorithmFloat myAlgorithm;
}
